package ExpressTwo;

import javax.swing.*;
import javax.swing.table.DefaultTableModel;

public class LeastRecentlyUsed {
    private final MainInterface _D;
    LeastRecentlyUsed(MainInterface d){
        _D=d;
    }
    //更改LRU的内容
    void change() {
        change_center();
    }

    void change_center() {
        //左边是8个标签，
        //分别是：0 块号，1 物理地址，2 是否缺页，3 是否置换，4 缺页次数，5 置换次数，6 缺页率，7 置换率

        JTable table = _D.getLru_table1();
        //中间是表格的东西，表格分别含有：0 页号，1 块号，2 状态
        //需要根据，计算出来的页号，然后从位示图中读取一个存储位置，然后放置相应的位置
        int page = _D.logicAddress / (_D.blockSize * 1024);
        int blockID;
        //设置块号
        //lru的这部分与fifo相比，有不同之处，应该修改


        if ("0".equals(table.getValueAt(page, 2))) {
            //如果是缺页
            //Node saved = _D.list_fifo.removeHead();
            if (_D.list_bitMapLRU.getLength() != 0) {
                //块未满
                blockID = _D.list_bitMapLRU.removeHead();//从位示图中选择
                JTable bit=_D.getBitMap_table();
                bit.setValueAt("1",blockID/table.getColumnCount(),blockID%table.getColumnCount());

                table.setValueAt(blockID, page, 1);//设置块号
                table.setValueAt("1", page, 2);//设置状态
                _D.list_lru.add(new Node(page, blockID));//把这一队添加到该队列中

                //缺页++
                //_D.lruNeedPage++;
                //更新状态
                //缺页状态和置换状态
                _D.setLabels_lru(2, "是");
                _D.setLabels_lru(3, "否");
            } else {
                //块已用满
                //取消旧的状态
                Node saved = _D.list_lru.removeHead();
                table.setValueAt("0", saved.page, 2);//设置状态
                table.setValueAt("", saved.page, 1);//设置块号

                //更新状态
                table.setValueAt("1", page, 2);//设置状态
                table.setValueAt(String.valueOf(saved.block), page, 1);//设置块号
                _D.list_lru.add(new Node(page,saved.block));//块移除了，还得重新添加

                //?????
                //_D.lruNeedChange++;
                //更新状态

                _D.setLabels_lru(2, "是");
                _D.setLabels_lru(3, "是");
            }
            //更新状态
            _D.setLabels_lru(0, String.valueOf(table.getValueAt(page, 1)));//设置块号

            int pos = (Integer.parseInt(String.valueOf(table.getValueAt(page, 1))))* 1024 + _D.pageAddress;
            _D.setLabels_lru(1, "0x "+Integer.toHexString(pos)+"H");

        } else {
            //不是缺页
            //直接更新状态
            _D.setLabels_lru(0, String.valueOf(table.getValueAt(page, 1)));//设置块号

            int pos = Integer.parseInt(String.valueOf( table.getValueAt(page, 1))) * 1024 + _D.pageAddress;
            _D.setLabels_lru(1, "0x "+Integer.toHexString(pos)+"H");

            _D.setLabels_lru(2, "否");
            _D.setLabels_lru(3, "否");

        }
        change_right(page);

        _D.setLabels_lru(4, String.valueOf(_D.lruNeedPage));
        _D.setLabels_lru(5, String.valueOf(_D.lruNeedChange));
        _D.setLabels_lru(6, (((double) _D.lruNeedPage) / _D.accessCount) * 100 + " %");
        _D.setLabels_lru(7, (((double) _D.lruNeedChange) / _D.accessCount) * 100 + " %");

        //记录页号顺序
    }

    //更改右边部分
    void change_right(int page) {
        //先进先出置换流程
        boolean flag=false;
        DefaultTableModel d=(DefaultTableModel)_D.getLru_table2().getModel();
        for(int i=0;i<_D.stack_lru.getLength();i++){
            if(_D.stack_lru.get(i)==page){
                flag=true;
                //如果存在
                //那么先取出来，然后添加到最后的位置
                _D.stack_lru.add(_D.stack_lru.remove(_D.stack_lru.get(i)));
                break;
            }
        }
        if(!flag){
            //如果没有找到，那么就把其头去掉，从尾部增加一个值
            if(_D.stack_lru.getLength()==_D.blockNumber)
                _D.stack_lru.removeHead();
            _D.stack_lru.add(page);
        }
        //下面是显示内容
        String[]show={"","","",""};
        show[0]=String.valueOf(d.getRowCount());
        show[1]=String.valueOf(page);
        for(int i=0;i<_D.stack_lru.getLength();i++){
            show[2]=show[2]+" "+_D.stack_lru.get(i)+" ";
        }
        if(!flag){
            show[3]="√";
            _D.lruNeedPage++;//缺页次数增加
            if(_D.stack_lru.getLength()==_D.blockNumber&&_D.lruNeedPage!=_D.blockNumber)
                _D.lruNeedChange++;//置换次数增加
        }
        else{
            show[3]="×";
        }
        d.addRow(show);
    }
}
